﻿#ifndef AXDP_BIN_PARSER_H_
#define AXDP_BIN_PARSER_H_

// #include "axdp_defines.h"

#include <cstdint>
#include <string>
#include <vector>

#define AXDP_BUILD_SHARED
#ifndef AXDP_API
#  ifdef _WIN32
#     if defined(AXDP_BUILD_SHARED) /* build dll */
#         define AXDP_API __declspec(dllexport)
#     elif !defined(AXDP_BUILD_STATIC) /* use dll */
#         define AXDP_API __declspec(dllimport)
#     else /* static library */
#         define AXDP_API
#     endif
#  else
#     if __GNUC__ >= 4
#         define AXDP_API __attribute__((visibility("default")))
#     else
#         define AXDP_API
#     endif
#  endif
#endif

#define AXDP_VERSION_MAJOR 1
#define AXDP_VERSION_MINOR 0
#define AXDP_VERSION ((AXDP_API_VERSION_MAJOR << 16) | AXDP_API_VERSION_MINOR)

namespace axdp {

    enum class UpdateStrategy : uint32_t {
        Falcon = 0x00100000,    //v20 like
        Dolphin = 0x00200000,   //a20 like
        Gopher = 0x00300000,    //c20 like
        Viper = 0x00400000,        //c30rk like
        Cobra = 0x00500000,     //for prd test
        Gecko = 0x00600000,     //Ceilingmic like A50
        Discus = 0x00700000,    //A50 DSP
        Camel = 0x00800000,        //A50 ctrl
    };

    enum ErrorCode : int32_t {
        /**
        * 成功，无异常
        */
        Success = 0,
        /**
        * 升级文件异常
        */
        FileAbnormal,
        /**
        * 升级文件校验失败
        */
        FileVerifyFailed,
        /**
        * 通信异常
        */
        TransportFailed,
        /**
        * 设备内部异常
        */
        InsideAbnormal,
    };

    enum class ResultState : int32_t {
        Failed = -1,
        Success = 0
    };

    enum class VideoMode : uint32_t {
        PanoramicView = 0,
        SmartTracking = 1 //auto framing
    };

    enum class VideoTrackMode : uint32_t {
        NoTrack = 0,
        SingleSpeaker = 1,
        SplitScreens = 2,
        ZoneFollowing = 3,
        Manual = 4,
        PanoramaShot = 5,
        AutoFraming = 6
    };

    enum class SpeakerTrackDelay : uint32_t {
        MinDelaySecond = 1,
        MaxDelaySecond = 5
    };

    enum class EnableState : uint32_t {
        Disabled = 0,
        Enabled = 1
    };

    enum class PowerlineFreqType : uint32_t {
        Freq50Hz = 1,
        Freq60Hz = 2
    };

    enum class UpgradeState {
        DataReady,      //数据准备完成，向设备请求升级
        Transferring,   //数据传输中，此时开始progress变化
        Verifying,      //传输完成，等待数据确认
        Success,        //设备升级成功，等待重启
        Failed
    };

    typedef struct DeviceInformationSt {
        uint16_t dev_type;
        char product_name[64];
        char phy_version[64];
        char soft_version[64];
        char serial_number[64];
        char unique_id[64];
    } DeviceInfo;

    typedef struct RoiRectSt {
        int left;
        int right;
        int top;
        int bottom;
    } RoiRect;

    enum class HIDEvent {
        Mute,
        Unmute,
        Answer,
        HangUp,
        VolDown,
        VolUp
    };

    enum class DegreeLevel : int8_t {
        UltraLow = 0,
        Low = 1,
        Medium = 2,
        High = 3,
        UltraHigh = 4
    };


    /*
    音频类型
        0x01 PCM, 0x02 OggOpus
    采样率
        16000，32000， 48000
    声道数
        1 单声道， 2 双声道，
    采样位宽
        以字节算
    */
    typedef struct AudioFormat {
        uint32_t            audio_type;
        uint32_t            sample_rate;
        uint32_t            channel_num;
        uint32_t            bit_width;
    }AudioFormat;
}



namespace axdp {
    class BinParser {
    public:
        BinParser();

        ~BinParser();

        int loadLocalFile(const char *file_name);

        int loadMemBuffer(const char *buffer, size_t size);//will copy

        int parseContent();

        int parseContent(std::vector<std::string>& file_list);

        const uint8_t *md5Buffer(int idx) const;

        const uint8_t *blockBuffer(int idx) const;

        size_t blockLength(int idx) const;

        const uint8_t *data() const { return content_; }

        size_t dataLength() const { return size_; }

        int getBlockNum(){return m_block_number;}

    private:
        int recoverData();

        int checkAuditoryHead();

        uint8_t *content_;
        
        size_t size_;

        //auditory fingerprint
        int32_t header_offset_;

#define MAX_BLOCKS_NUM 8
        uint32_t block_md5_offset_[MAX_BLOCKS_NUM];
        uint32_t block_offset_[MAX_BLOCKS_NUM];
        uint32_t block_length_[MAX_BLOCKS_NUM];
        int m_block_number;
    };
}


#endif // !AXDP_BIN_PARSER_H_



